﻿using System.Collections.Generic;
using TextEditor.TextBoxInner.DrawingElements;
using TextEditor.TextBoxInner.Utils;

namespace TextEditor.TextBoxInner.Layers
{
	internal class NumberLayer : LayerBase<NumberLine>
	{
		private readonly static NumberLineCreator _numberLineCreator = new NumberLineCreator();

		private readonly List<NumberLine> _tempInvisibleList = new List<NumberLine>(50);
		private readonly List<NumberLine> _tempCandidateseList = new List<NumberLine>(50);

		public NumberLayer() : base(_numberLineCreator)
		{ }

		public void SetLines(int[] linesIndexes)
		{
#if DEBUG
			//System.Diagnostics.Debug.Assert(linesIndexes.Length < Children.Count);
#endif

			try
			{
				if (linesIndexes.Length == 0)
				{
					for (int index = 0; index < Children.Count; index++)
						Children[index].SetContent(null);

					return;
				}

				_tempInvisibleList.Clear();
				_tempCandidateseList.Clear();

				int startIndex = linesIndexes[0];
				int endIndex = linesIndexes[linesIndexes.Length - 1];

				int startCandidatesIndex = -1;
//				int endCandidatesIndex = -1;

				for (int index = 0; index < Children.Count; index++)
				{
					NumberLine line = Children[index];

					if (!line.IsVisible)
					{
						_tempInvisibleList.Add(line);
						continue;
					}

					if (line.LineIndex < startIndex)
					{
						_tempInvisibleList.Add(line);
						continue;
					}

					if (line.LineIndex > endIndex)
					{
						_tempInvisibleList.Add(line);
						continue;
					}

					_tempCandidateseList.Add(line);

//					endCandidatesIndex = line.LineIndex;

					if (startCandidatesIndex < 0)
						startCandidatesIndex = line.LineIndex;
				}

				for (int index = 0; index < linesIndexes.Length; index++)
				{
					int itemIndex = linesIndexes[index];

					if (itemIndex == startCandidatesIndex)
					{
						for (int marker = 0; marker < _tempCandidateseList.Count; marker++)
							Children[index + marker] = _tempCandidateseList[marker];

						index += _tempCandidateseList.Count - 1;
					}
					else
					{
						int tempElementIndex = _tempInvisibleList.Count - 1;
						NumberLine temp = _tempInvisibleList[tempElementIndex];
						_tempInvisibleList.RemoveAt(tempElementIndex);

						Children[index] = temp;
						temp.SetContent(itemIndex);
					}
				}

				for (int index = linesIndexes.Length; index < Children.Count; index++)
				{
					int tempElementIndex = _tempInvisibleList.Count - 1;
					NumberLine temp = _tempInvisibleList[tempElementIndex];
					_tempInvisibleList.RemoveAt(tempElementIndex);

					Children[index] = temp;
					temp.SetContent(null);
				}

				for (int index = 0; index < Children.Count; index++)
					Children[index].SetTop(index * FontHelper.FontHeight);
			}
			finally
			{
				InvalidateVisual();
			}
		}

		private class NumberLineCreator : DrawingElementFactory<NumberLine>
		{
			internal override NumberLine Create()
			{
				return new NumberLine();
			}
		}
	}
}
